package com.impress.service;

import java.io.InputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.impress.Utility;
import com.impress.Utility.HttpForbiddenException;
import com.impress.Utility.HttpUnauthorizedException;
import com.impress.Utility.InvalidTokenException;

public class GDataClient {

	
	private static final String USER_AGENT = "MobileGR(gzip)";
	
	/**
	 * Do a HTTP request, returning the response entity.
	 * @param request
	 * @return
	 * @throws Exception
	 */
	private static HttpEntity callMethod(HttpUriRequest request)throws Exception{
		request.addHeader("Accept-Encoding", "gzip");

		DefaultHttpClient httpClient = new DefaultHttpClient();
		
		//设置超时
		HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 20*1000);
		HttpConnectionParams.setSoTimeout(httpClient.getParams(), 20*1000);
		
		HttpProtocolParams.setUserAgent(httpClient.getParams(), USER_AGENT);
		
		HttpResponse response = null;
		HttpEntity entity = null;
		
		//do the request.
		response = httpClient.execute(request);
		if(response.getStatusLine().getStatusCode()==200){
			entity = response.getEntity();
		}
		else if(response.getStatusLine().getStatusCode() == 403){
			//TODO throw exception
			throw new HttpForbiddenException("login has been failed: " + response.getStatusLine().toString());
		}
		else if(response.getStatusLine().getStatusCode() == 401){
			//TODO throw exception
			throw new HttpUnauthorizedException("auth token has been expired");
		}
		else if (response.getStatusLine().getStatusCode() == 400) {
			Header header = response.getFirstHeader("X-Reader-Google-Bad-Token");
			if(header!=null && header.getValue().equalsIgnoreCase("true") ){
				throw new InvalidTokenException("token has been expired");
			}else {
				throw new Exception("HTTP 400: " + EntityUtils.toString(response.getEntity()));
			}
		}
		else{
			//TODO throw exception
			throw new Exception("Bad response: " + response.getStatusLine().toString());
		}
		
		return entity;
	}
	
	
	/**
	 * Do a HTTP request
	 * @param request
	 * @param auth Google auth token.
	 * @return
	 * @throws Exception
	 */
	private static String callMethod(HttpUriRequest request, String auth)throws Exception{
		//set auth header
		if (auth!=null) {
			request.addHeader("Authorization", "GoogleLogin auth="+auth);
		}
		
		InputStream stream = getInputStream(callMethod(request));
		if (stream != null) {
			byte[] bResult = Utility.convertStreamToBytes(stream);
			if (bResult != null) {
				String responseString = new String(bResult, "utf-8");
				return responseString;
			}
		}
		return "";
	}

	/**
	 * get inputstream from the http entity. if entity is gziped, then wrap the inputstream with GzipInputStream
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	private static InputStream getInputStream(HttpEntity entity) throws Exception{
		InputStream is = entity.getContent();
		if (is != null) {
			Header header = entity.getContentEncoding();
			if (header != null) {
				if (header.getValue().contains("gzip")) {
					is = new GZIPInputStream(is);
				}
			}
		}
		return is;
	}

	/**
	 * 发起一个Get请求
	 * @param url 请求的网址
	 * @param queryString 请求的参数
	 * @param auth	用于身份验证
	 * @return 返回取得的流，失败则为null
	 */
	public static String doGet(String url, String queryString, 
			String auth) throws Exception{		
		if(queryString!=null)
			url = String.format("%s?%s", url, queryString);

//		if(!url.startsWith(Utility.GOOGLE_LOGIN_URL) && !url.contains("feeds.feedburner.com")){
//			url.replace(Utility.READER_URL, "http://www.google.com/reader");
//		}
		HttpGet httpGet = new HttpGet(url);
		return callMethod(httpGet, auth);
	}

	/**
		 * 发起一个HTTP Post请求
		 * @param url 请求的网址
		 * @param params 请求的post参数
		 * @param auth 添加进请求头的参数，当做第一次登录的时候可以为空
		 * @return 返回post完后从网站返回取得的流，失败则返回NULL
		 * @throws Exception 
		 * (HttpForbiddenException, HttpUnauthorizedException, ConnectTimeoutException, SocketTimeoutException, Exception)
		 */
	public static String makePost(String url, List<NameValuePair> params, 
			String auth) throws Exception{
		HttpPost httpPost = new HttpPost(url);

		httpPost.setEntity(
				new UrlEncodedFormEntity(params, HTTP.DEFAULT_CONTENT_CHARSET));

		return callMethod(httpPost, auth);
	}

	/**
	 * Do a HTTP Get request, and return the response as byte array.
	 * @param url the url of the image.
	 * @param path the path used to save the image.
	 * @return
	 */
	public static byte[] doGet(String url)throws Exception{
		HttpGet httpGet = new HttpGet(url);
		HttpEntity entity = callMethod(httpGet);
		InputStream stream = getInputStream(entity);
		byte[] bResult = null;
		if (stream != null) {
			bResult = Utility.convertStreamToBytes(stream);
		}
		return bResult;
	}

}
